package com.mec.offload.controller;

import com.alibaba.fastjson.JSONObject;
import com.mec.offload.model.*;
import com.mec.offload.service.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import java.util.*;
import java.util.stream.Collectors;

@Controller
@RequestMapping("/offload/AltTask")
@CrossOrigin
public class AltTaskController {
    @Autowired
    private AltTaskService altTaskService;
    @Autowired
    private SubTaskService subTaskService;
    @Autowired
    private TaskLinkService taskLinkService;
    @Autowired
    private NodeTermService nodeTermService;
    @Autowired
    private MecService mecService;
    @Autowired
    private OffloadSubTaskService offloadSubTaskService;
    //得到每个终端的所有任务
//    @CrossOrigin(origins = "*")
    @RequestMapping("/getTaskByTermId")
    @ResponseBody
    public List<AltTask> get(Integer termId){
        try{

            return altTaskService.getTaskByTermId(termId);
        }catch (Exception e){
            e.printStackTrace();
            return null;
        }
    }
    @RequestMapping("/test")
    @ResponseBody
//    @CrossOrigin
//    @ResponseBody
    public String test(){

        System.out.println("11111111 ");
        return "123456";
    }

    //切割3：拓扑图展示（得到所有子任务并展示成图）
//    @CrossOrigin(origins = "*")
    @RequestMapping("/getMissionShow")
    @ResponseBody
    public TaskForShow getMission(Integer TaskId){
        try {
            //得到该父任务对应的所有子任务
            List<SubTask> listS=subTaskService.getSubMission(TaskId);
            //得到topo的边（不用）
            List<TaskLink> listT=taskLinkService.getTaskLinkById(TaskId);
            TaskForShow taskForShow=new TaskForShow();
            taskForShow.setListS(listS);
            taskForShow.setListT(listT);
            return taskForShow;
        }catch (Exception e){
            e.printStackTrace();
            return null;
        }
    }

    //切割1：子任务是否需要被卸载，将多个子任务锁定到个别的，改变isdepart字段，也改变sig字段
//    @CrossOrigin(origins = "*")
    @RequestMapping("/UpdateSigStep1")
    @ResponseBody
    public int updateTask(Integer TaskId){
        try {
            int flag=0;
            List<SubTask> listS=subTaskService.getSubMission(TaskId);//所有子任务
            for(int i=0;i<listS.size();i++){
                flag=1;
                Integer subTaskId=listS.get(i).getSubTaskId();
                List<TaskLink> links=taskLinkService.findTaskLinkRe(subTaskId);//找到与此子任务相连的边
                Double costTele=0.0;
                for (int j=0;j<links.size();j++)
                    costTele+=links.get(j).getCost();//子任务所有边的通信代价
                if(costTele<=listS.get(i).getEnergyCost())
                    subTaskService.SubTaskToMs(listS.get(i).getSubTaskId());
                else {
                    subTaskService.SubTaskToTs(listS.get(i).getSubTaskId());//移动到TS集合
                    //计算本地执行代价
                    NodeTerm nodeTerm=nodeTermService.getOriTaskTerm(listS.get(i).getOriTaskId());
                    Double cost_loc;
                    Double L_loc=listS.get(i).getSubTaskRes()
                            /nodeTerm.getTermRate();
                    Double E_loc=L_loc*nodeTerm.getTermRunPower();
                    cost_loc=(L_loc+E_loc)/2;//权重均为1/2
                    listS.get(i).setCostLoc(cost_loc);
                    subTaskService.updateSubTask(listS.get(i));
                }
            }
            altTaskService.updateTaskDepart(TaskId);//划分完毕可进行决策
            return flag;
        }catch (Exception e){
            e.printStackTrace();
            return 0;
        }
    }


    /*1.NodeTerm三项增加根据源任务id找到NodeTerm的函数，用于寻找NodeTerm(含Floc，传输速度，执行和传输Power)
        2.MEC执行情况放到数组内，寻找最小值计算
        * */
    //决策1：判断是否可以决策
//    @CrossOrigin(origins = "*")
    @RequestMapping("/Judge")
    @ResponseBody
    public int DealWithSubTaskJudge(Integer TaskId){
        try{
            List<SubTask> listS=subTaskService.getTaskByTaskOffload(TaskId);//找到MS中的子任务
            NodeTerm nodeTerm=nodeTermService.getOriTaskTerm(TaskId);//找到执行该任务的终端
            List<MEC> listM= mecService.getAllMec();
            for(int i=0;i<listS.size();i++){
                Double cost_loc=0.0;
                Double L_loc=listS.get(i).getSubTaskRes()
                        /nodeTerm.getTermRate();
                Double E_loc=L_loc*nodeTerm.getTermRunPower();
                cost_loc=(L_loc+E_loc)/2;//权重均为1/2
                Double [] Cost=new Double[5];
                for(int j=0;j<listM.size();j++){
                    Double t1=listS.get(i).getSubTaskBite()
                            /nodeTerm.getDataTranRate();
                    Double t_exe=listS.get(i).getSubTaskRes()/listM.get(j).getMecRate();
                    Double L_up=t1+t_exe;
                    Double E_up=t1
                            * nodeTerm.getTermTranPower()/1000
                            +listM.get(j).getConnectPower()
                            *t_exe;
                    Cost[j]=(L_up+E_up)/2;//上传代价
                }
                Double min= Collections.min(Arrays.asList(Cost));
                Double max=Collections.max(Arrays.asList(Cost));
                SubTask subTask=new SubTask();
                subTask.setSubTaskId(listS.get(i).getSubTaskId());
                subTask.setCostLoc(cost_loc);
                subTask.setCostTran(min);
                subTaskService.updateSubTask(subTask);
                if(cost_loc<=min) {
                    subTaskService.SubTaskToTs(listS.get(i).getSubTaskId());
                    //subTaskService.
                }
                altTaskService.updateTaskJudge(TaskId);
            }
            return 1;
        }catch (Exception e){
            e.printStackTrace();
            return 0;
        }
       // return subTaskService.getSubTaskInMsOnce(TaskId);
    }

    //卸载结果对比表格展示
//    @CrossOrigin(origins = "*")
    @RequestMapping("/getFeedBack")
    @ResponseBody
    public List<AltTaskFeedBack> getFeedBack(){
    try {
        List<AltTaskFeedBack> listF=new ArrayList<AltTaskFeedBack>();
        List<AltTask> ListDone=altTaskService.getAllTaskDone();
        for(int i=0;i<ListDone.size();i++){
            Integer TaskId=ListDone.get(i).getTaskId();
            List<OffloadSubTask> listO=offloadSubTaskService.getDoneOffloadTask(TaskId);//offload中已完成的任务
            List<SubTask> listS=subTaskService.getTaskByTaskOffload(TaskId);//卸载到MEC任务
            if(listO.size()==listS.size()&&listO.size()!=0){
                AltTaskFeedBack altTaskFeedBack=new AltTaskFeedBack();
                altTaskFeedBack.setAltTaskId(TaskId);
                List<SubTask> listM=subTaskService.getSubMission(TaskId);
                altTaskFeedBack.setListSub(listM);
                double ori_cost=0.0;
                double after_cost=0.0;
                for(int j=0;j<listM.size();j++)
                {
                    ori_cost+=listM.get(j).getCostLoc();
                    if(listM.get(j).getSig()==0)
                        after_cost+=listM.get(j).getCostLoc();
                    else
                        after_cost+=offloadSubTaskService.getOffloadTaskBySubId(listM.get(j).getSubTaskId()).getCostTran();
                }
                altTaskFeedBack.setCostWithoutJudge(ori_cost);
                altTaskFeedBack.setCostWithJudge(after_cost);
                listF.add(altTaskFeedBack);
            }
        }
        return listF;
    }catch (Exception e){
        e.printStackTrace();
        return null;
    }
    }

    //docin 终端的父任务列表分页展示
//    @CrossOrigin(origins = "*")
    @RequestMapping("/getTaskByTermIddou")
    @ResponseBody
    public String getdou(Integer termId,@RequestParam(required=false,defaultValue="1") int page,
                             @RequestParam(required=false,defaultValue="10") int limit){
        try{
            List<AltTask>datas = altTaskService.queryAllDataFromTable(page,limit,termId);
            int countx=  altTaskService.queryfuAllCount(termId);
            JSONObject jo = new JSONObject();
            jo.put("code",0);
            jo.put("msg","");
            jo.put("count",countx);
            jo.put("data", datas);
            return jo.toString();
        }catch (Exception e){
            e.printStackTrace();
            return null;
        }
    }

    //docin 终端的父任务列表分页展示
//    @CrossOrigin(origins = "*")
    @RequestMapping("/getTaskByMultiTermIdArraydou")
    @ResponseBody
    public String getTaskByMultiTermIdArray(@RequestParam("terminalArray[]") Integer[] terminalArray,@RequestParam(required=false,defaultValue="1") int page,
                         @RequestParam(required=false,defaultValue="10") int limit){
        try{

            List<AltTask> allData=new ArrayList<AltTask>();
            int allCount=0;
            for(int i=0;i<terminalArray.length;i++){

                List<AltTask>datas = altTaskService.queryAllDataFromTable(page,limit,terminalArray[i]);
                int countx=  altTaskService.queryfuAllCount(terminalArray[i]);
                for(int j=0;j<datas.size();j++){
                    allData.add(datas.get(j));
                }
                allCount=allCount+countx;
            }
            for (AltTask allDatum : allData) {
                System.out.println(allDatum.toString());
            }
            JSONObject jo = new JSONObject();
            jo.put("code",0);
            jo.put("msg","");
            jo.put("count",allCount);
            jo.put("data", allData);
            return jo.toString();
//            System.out.println(termimalArray.length);
//            return null;
        }catch (Exception e){
            e.printStackTrace();
            return null;
        }
    }

    //确定卸载的子任务写进  OFFLOAD_TASK数据库表
    public int addOffload(Integer oriTaskId){
        try {
            List<SubTask>listS=subTaskService.getTaskByTaskOffload(oriTaskId);
            for(int i=0;i<listS.size();i++){
                OffloadSubTask offloadSubTask=new OffloadSubTask();
                offloadSubTask.setOffloadNum(listS.get(i).getSubTaskNum());
                offloadSubTask.setSubTaskId(listS.get(i).getSubTaskId());
                offloadSubTask.setOriTaskId(listS.get(i).getOriTaskId());
                offloadSubTask.setOriTermId(nodeTermService.getOriTaskTerm(oriTaskId).getTermId());
                offloadSubTask.setCostTran(0.0);
                offloadSubTask.setOffMecId(-1);
                offloadSubTask.setEnergyCost(0.0);
                offloadSubTaskService.addToOffloadTask(offloadSubTask);
            }
            return 1;
        }catch (Exception e){
            e.printStackTrace();
            return 0;
        }
    }

    //和弹窗中的切分按钮匹配
    //切割决策 返回子id父id终端ID和sig标签
    //sig=0不用卸，sig=1卸，若sig全为0则该父任务不可被切割，只能在本地执行
//    @CrossOrigin(origins = "*")
    @RequestMapping("/getSubTaskdou")
    @ResponseBody
    public String getSubTaskdou(@RequestParam(required=false,defaultValue="1") int page,
                                @RequestParam(required=false,defaultValue="10") int limit,Integer TaskId)
    {
        try{
            updateTask(TaskId);
            DealWithSubTaskJudge(TaskId);
            addOffload(TaskId);
            List<SubTask>datas = subTaskService.queryAllDataFromTable(page,limit,TaskId);
            List<SubTask> listO = datas.stream().sorted(Comparator.comparing(SubTask::getSubTaskId))
                    .collect(Collectors.toList());
            int countx = subTaskService.queryziAllCount(TaskId);
            JSONObject jo = new JSONObject();
            jo.put("code",0);
            jo.put("msg","");
            jo.put("count", countx);
            jo.put("data", listO);
            return jo.toString();
        }catch (Exception e){
            e.printStackTrace();
            return null;
        }
    }

    //给学姐返回切分动画数据
//    @CrossOrigin(origins = "*")
    @RequestMapping("/getSubTaskdonghuadou")
    @ResponseBody
    public List<SubTask> getSubTaskdonghuadou(Integer TaskId)
    {
        try{
            List<SubTask> list = subTaskService.getSubMission(TaskId);
            List<SubTask> listO = list.stream().sorted(Comparator.comparing(SubTask::getSubTaskId))
                    .collect(Collectors.toList());
            //按照子任务id来返回
            return listO;
        }catch (Exception e){
            e.printStackTrace();
            return null;
        }
    }

    //给学姐返回切分动画数据
//    @CrossOrigin(origins = "*")
    @RequestMapping("/getMultiSubTaskdonghuadou")
    @ResponseBody
    public List<SubTask> getMultiSubTaskdonghuadou(@RequestParam("taskArray[]")Integer[] taskArray)
    {
        try{

            List<SubTask> allData=new ArrayList<SubTask>();
            for(int i=0;i<taskArray.length;i++){
                updateTask(taskArray[i]);
                DealWithSubTaskJudge(taskArray[i]);
                addOffload(taskArray[i]);
                List<SubTask> list = subTaskService.getSubMission(taskArray[i]);
                List<SubTask> listO = list.stream().sorted(Comparator.comparing(SubTask::getSubTaskId))
                        .collect(Collectors.toList());
                for(int j=0;j<listO.size();j++){
                    allData.add(listO.get(j));
                }
            }
            //按照子任务id来返回
            return allData;
        }catch (Exception e){
            e.printStackTrace();
            return null;
        }
    }

}
